Conversation
🟡 Heimdall Review Status
🟡
|
| Code Owner | Status | Calculation | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| ui-systems-eng-team |
🟡
0/1
|
Denominator calculation
|
15d5c80 to
1f1f05e
Compare
hcopp
left a comment
There was a problem hiding this comment.
Love the idea! Hopefully this can help you talk with Cursor about how to clean things up.
Also if you could get sample screenshots, description of your intended changes, and a link to the figma in the PR description that would be very helpful!
apps/docs/static/img/campaignCardBanners/color-pairing-tool_dark.png
Outdated
Show resolved
Hide resolved
apps/docs/src/components/page/ColorPairingTool/ComponentPlayground.tsx
Outdated
Show resolved
Hide resolved
apps/docs/src/components/page/ColorPairingTool/ComponentPlayground.tsx
Outdated
Show resolved
Hide resolved
apps/docs/src/components/page/ColorPairingTool/ContrastPanel.tsx
Outdated
Show resolved
Hide resolved
apps/docs/src/components/page/ColorPairingTool/HotspotImagePreview.tsx
Outdated
Show resolved
Hide resolved
| CDS layout components use inline styles generated from their style props, | ||
| which have higher specificity than CSS class rules. !important is required | ||
| here to override those inline styles at mobile breakpoints. | ||
| ────────────────────────────────────────────────────────────────────────── */ |
There was a problem hiding this comment.
We shouldn't need to use style props, but instead use our regular component props which support responsive values.
There was a problem hiding this comment.
cursor:
Here's a comment you can post:
Acknowledged — the !important overrides in ResultCard.module.css exist because CDS layout components (HStack, VStack, Box) apply style props as inline styles, which have higher specificity than CSS class rules. The fix is to replace these with responsive CDS component props (e.g. flexDirection={{ base: 'column', tablet: 'row' }}, width={{ base: '100%', tablet: '50%' }}).
We've already done this for ColorPicker.module.css (removed the .pickerRow !important override in this round). The remaining overrides in ResultCard.module.css touch layout across ResultCard, ComponentPlayground, and ContrastPanel simultaneously and need visual QA at both desktop and mobile breakpoints. Deferring to a dedicated follow-up PR.
|
@nicoledbelcher are you able to fill out the PR description? This is done in GitHub UI manually. You can look at other PRs to see what we normally do to fill it out.
Also your commits are unverified, you should follow https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account. This is a requirement to merge in code. Lastly, can you pull in the latest from master? Cursor can help with this. |
Adds ColorPairingTool to docs site, color-pairing utilities and components to vite-app, cds-finder app, guidelines documentation, and various supporting updates. Made-with: Cursor
…heming - Remove Color matching / Color pairs tab strip; single-flow layout - Scope LineChart scrubber overlay/line CSS vars to chart card for light playground - Hue-aware primitive matching and related adjustments Made-with: Cursor
…ixes - Checkerboard thumbnails in UploadZone now respect light/dark color mode - Light mode thumb borders use subtle dark borders instead of invisible white - Restore top padding on contrast panel for proper spacing on mobile - Increase mobile image preview height to 300px for balanced blur padding - Fix hotspot drifting off image on mobile by removing align-items stretch - Fix cards row clipping LineChart on mobile by overriding fixed height - Strip trailing commas in color input instead of creating phantom results - Remove red error outline when typing a trailing comma - Remove token tag next to "Color match to components" heading Made-with: Cursor
- Move reducer/initialState into parent component (index.tsx), rename state.ts to types.ts for shared type definitions only - Remove sharedStyles.ts (CoinbaseMono font not available in docs) - Move hotspot label inline styles to ResultCard.module.css - Use CDS Box props instead of inline styles in ContrastPanel - Replace checker-placeholder.png with theme-aware inline SVG - Replace banner PNGs with SVGs for light/dark modes - Simplify LineChart height prop (remove unnecessary responsive object) - Hide MetadataLinks on pages with no metadata (e.g. playground) - Run docs:lint --fix (all files pass) Note: the style props → responsive CDS props refactor (removing !important overrides in ResultCard.module.css) is deferred to a follow-up. It touches the responsive layout across multiple components and needs careful visual QA at both desktop and mobile breakpoints. Made-with: Cursor
…mprove playground - Extract PlaygroundContent into its own file for cleaner separation - Extract generic FileDropZone component and useFileUpload hook for reuse - Replace hardcoded spectrum values and types in tokens.ts with CDS theme imports - Remove unused CSS modules and useImageUpload hook - Simplify ContrastPanel and WcagBadge to use CDS spacing props - Update LineChart card background to use "bg" token - Add hideLlmLink option to MetadataLinks component - Fix ContentHeader bannerHeight JSDoc format Made-with: Cursor
fafe4f6 to
2c12130
Compare
|
|
||
| export type TokenFamily = ThemeVars.SpectrumHue; | ||
| export type TokenStep = ThemeVars.SpectrumHueStep; | ||
| export type ColorToken = ThemeVars.SpectrumColor; |
There was a problem hiding this comment.
nit: we shouldn't need to re-export TokenFamily, TokenStep, ColorToken, lightSpectrum, and darkSpectrum. Files importing from here should instead import from useTheme(), or, if unable, import from defaultTheme.

What changed? Why?
Added a new sidebar to the docs site called extras and created a new color pairing tool inside it.
What it is
The Color Pairing Tool is an internal design utility built into the CDS documentation site. It helps designers and engineers find the closest CDS spectrum primitives for any color and automatically generates accessible, theme-aware color pairings that work across light and dark modes.
How it works
Image upload — Users can upload up to 10 images (PNG, JPG, or WebP) via file picker or drag-and-drop. The tool extracts dominant colors from each image using a k-means clustering algorithm run client-side on an .
Manual hex entry — Users can type one or more comma-separated hex codes directly into a text input.
2. Token Matching
For each extracted or entered color, the tool runs a hue-aware matching algorithm against the full CDS spectrum (both light and dark). This isn't a simple "nearest Euclidean distance" match — it's purpose-built for CDS tokens and factors in perceptual hue so the matched primitive feels like a natural fit, not just the mathematically closest one.
Once a primary background token is matched, the tool:
Selects a foreground text color that meets WCAG AA contrast requirements (minimum 4.5:1 for normal text).
Computes a secondary/complementary token pairing.
Offers a high-contrast mode toggle that enforces even stricter contrast ratios.
Displays live WCAG contrast ratios (AA Normal, AA Large, AAA) for every pairing.
4. Component Preview
The results feed into a Component Playground that renders real CDS components — Card, Button, MessagingCard, LineChart, ProgressBar, and more — using the matched token pairings. This gives an immediate preview of how the colors will look in a production UI across both light and dark themes.
For image uploads, users can drag a hotspot around the image to resample the dominant color from a different region, which recalculates the token match and all downstream pairings in real time.
Results can be exported as structured JSON containing the matched tokens, hex values, text colors, and button state variants for both light and dark modes — ready to hand off to engineering.
Key technical details
Runs entirely client-side — no server calls. All color math, image processing, and token matching happen in the browser.
Uses CDS design tokens as the source of truth (imported from tokens.ts), so matches always stay in sync with the design system.
Theme-aware throughout — every visual (checkerboards, previews, component playground) adapts to the user's current light/dark mode setting.
UI changes
Multiple outputs carousel:

Testing
You should test selecting a color from the color picker without uploading an image, and then test uploading one or multiple images. Users can only upload, PNG, JGP and WEBP files, no video/animated gif files allowed.
How has it been tested?
Testing instructions
Illustrations/Icons Checklist
Required if this PR changes files under
packages/illustrations/**orpackages/icons/**Change management
type=routine
risk=low
impact=sev5
automerge=false